/**
 * @copyright redmicro all Copyright (c)
 * @author Created by duyi on 2023/3/18.
 * @description 根据JsonSchema 绘制json 表单,包含 控件取值方式(selector,enum...) 设置
 * @description 对于不要显示但需要保存但数据（如：主键）的数据建议使用隐藏控件，有利于数据专递。
 * @description 不继承ModeForm ,防止因修改升级 ，互相干扰
 *
 */
Rsd.define('Rsd.widget.JsonForm', {
    extend: 'Rsd.container.Form',
    requires: [
        'Rsd.form.Text',
        'Rsd.form.TextArea',
        'Rsd.form.TextFK',
        'Rsd.form.Date',
        'Rsd.form.Time',
        'Rsd.form.Timestamp',
        'Rsd.form.Number',
        'Rsd.form.Hidden',
        'Rsd.form.Json',
        'Rsd.form.CheckBox',
        'Rsd.form.ComboBox',
        'Rsd.form.ComboBoxEx',
        'Rsd.form.ComboBoxEnum',
        'Rsd.form.Picker',
        'Rsd.form.Image',
        'Rsd.form.Images',
        'Rsd.control.HtmlBox',
        'Rsd.control.List',
        'Rsd.control.Grid',
        'Rsd.control.SearchToolBar'
    ],
    xtype: 'json-form',
    /**
     * 子控件背景色
     */
    bgColors:['#f0f8ffa1','#accfee59','#ebe9e7a1','#7d9fbda1','#dfe2eca1','#ded7cca1'],
    layout: {type:'vbox',align:'center'},
    height: 'auto',
    //fields 已加载
    //isLoaded:null,//null：未触发加载，false ：加载中，true ：已加载完毕
    readonly: true,
    errorList: [],
    /*
    * 对于不要显示但需要保存但数据（如：主键）的数据建议使用隐藏控件，有利于数据专递。
    * */
    formSchema: null,
    /**
     * 
     */
    fieldWidth: '45%',
    //最后一次加载的数据对象
    //data:{}, 
    /**
     * 
     */
    items: [],
    
    /**
     * 获取编辑按钮
     */
    getEditButtonsHandler:'',
    /**
     *  form编辑事件处理程序
     */
    formEventHandler:'',
    /*
     * */
    constructor: function JsonForm(config) {
        config = config || {};
        this.apply(config);
    },
    /*
    * */
    onAfterInit: function onAfterInit() {

        var me = this;
        me.callParent(); 
        if(me.formSchema)
        {  
            //console.trace('json form onAfterInit');
            setTimeout(function onAfterInit_SetTimeOut() {
  
                me.loadFields(me.formSchema);//render 之后会执行doLayout

                //出现滚动条 重新设置 该控件高度，不让该控件出现滚动条，让滚动条出现在该控件父控件中
                if (me.body.scrollHeight > me.body.clientHeight) {
                    var _scrollHeight = me.body.scrollHeight + 45; 
                    me.height = _scrollHeight;
                }

            }, 50);
        } 
       
    },
    /** 
    {
        a: {
            $id: a,
            title: ,
            description: ,
            required: true,
            type: string,
            minLength: 0,
            maxLength: 0,
            pattern: ,
            format: ,
            $ref: ,
            dependencies: null,
            minProperties: 0,
            maxProperties: 0,
            additionalProperties: false,
            enum: null,
            default: null,
            examples: [123],
            allOf: [],
            anyOf: [],
            oneOf: [],
            not: []
        }
    }
    * */
    loadFields: function loadFields(schema,callback) {

        //debugger;
        var me = this;  
        //console.trace('====>json form loadFields ==>>name is :',me.name);
        //console.log('form schema is',schema);

        var _readonly = me.readonly;
        var _schema = schema || {};
        var _fields = _schema.properties||[];
        if (Rsd.isEmpty(_fields)) {
            return;
        }
        
        //表单schema
        me.formSchema = _schema;
        var _w = 0;
        var _width = me.getWidth() || me.parent.getWidth();
        var _index = 0;
        var _last_type = "";
        var _bgIndex = 0;

        this.setElStyle('dom',{  
            borderRadius:'6px',
            backgroundColor:me.bgColors[_bgIndex]
        });
        //console.trace('loadFields ' + me.id);
        for (var p in _fields) {
            //debugger;
            var f = _fields[p];
            var _dataIndex = (me.dataIndex||'') + (Rsd.isEmpty(me.dataIndex)?'':'.') + (f.dataIndex || f.dataindex || f.name || p);
             
            _bgIndex = _index%me.bgColors.length;
            if( _index == _bgIndex)
            {
                _bgIndex = me.bgColors.length - _index%me.bgColors.length -1;
            }
            //console.log(p,f); 
            _index++;
            try {
                //类型处理
                var _xtype = f.xtype;
                //未指定编辑控件
                if(!_xtype)
                {
                    switch (f.type) {
                        case 'array': 
                            if(Rsd.isEmpty(f.items.oneOf) && Rsd.isEmpty(f.items.oneof))
                            {
                                //子元素的schema结构必须一致
                                 _xtype = 'grid';
                                  break;
                            }
                            if(Rsd.isArray(f.items.oneOf||f.items.oneof))
                            {
                                //子元素的schema结构允许不一致
                                _xtype = 'list';
                                 break;
                            }
                            console.error('array schema property items must be object or array',f)
                            break;
                        case 'object':
                             _xtype = 'json-form';
                            break;
                        case 'string':
                            _xtype = 'text';
                            break; 
                        case 'bool':
                        case 'boolean':
                            _xtype = 'checkbox';
                            break; 
                        default:  
                            _xtype = f.type||'text';
                            break;   
                    }
                }
                if(!_xtype)
                {
                    console.error('field config [xtype] has a error value',f);
                    continue;
                }
                //控件处理
                switch (_xtype) {
                    case 'grid': {   
                         //子元素数据结构结构一致
                        var _cols = [{xtype:'checkbox',text:'选择',keyMember:'key'}]; 
                        for(var c in f.items.properties)
                        {
                            var item = f.items.properties[c];
                            //console.log(c,item);
                            if(item.hidden === true)
                            {
                                continue;
                            }
                            _cols.push({
                                name: item.$id,
                                dataIndex: c,
                                text: item.title || item.$id,
                                xtype: item.type
                            });
                        }

                        _cols.push({
                            text: '操 作',
                            align: 'center',
                            schema: f,
                            width: 70,
                            format: function (row, parent) {

                                var _f = this.schema;
                                //console.log('op column buttons',_f.buttons);
                                var btns = [];
                                var _arr = _f.buttons||[];
                                for(var i = 0;i<_arr.length;i++)
                                {
                                    var _btn = _arr[i];
                                    if(btns.length > 0)
                                    {
                                         btns.push(Rsd.newLine());
                                    }
                                    btns.push(Rsd.link(_btn.text,function(row){
                                        me.funApplyByIOC(_btn.handler,[row]);
                                    }));
                                }
                                return btns;
                            }
                        });
 
                        //console.log('this are cols:',_cols);
                        //console.log('grid field info ',f); 
                        var _grid = {
                            xtype: 'grid',
                            margin:'0 0 10 2%',
                            width: '96%', 
                            //height: f.height || 100 + ((f.examples && f.examples.length) ||0) * 41, 

                            id: f.id || f.name || p,
                            name: f.name || p,
                            dataIndex: _dataIndex, 

                            ctrlStyle:{
                                overflow:'visible',
                            },
                            style:{
                                borderRadius:'4px',
                                backgroundColor:me.bgColors[_bgIndex],
                            },
                            label: {
                                xtype:'container',
                                position:'top',
                                align:'left',
                                header:{
                                     content:'&nbsp;&nbsp;' + (f.title || f.$id),
                                     position:'left'
                                },
                                space:0,
                                style: {  
                                    backgroundColor:'transparent', 
                                    fontSize:'100%', 
                                    lineHeight:40 
                                },
                                layout:{type:'hbox',align:'right'},
                                items:me.getDefaultButtons(p,f) //表格头部按钮
                            },
                            columns: _cols,
                            readonly: true,
                            border: true,
                            tabIndex: _index, 
                            dataSource: f.examples||[],
                            forSchema:_schema//根schema
                        };
 
                        _grid = me.add(_grid); 
                        //string 方法名注册事件，方法体中，this指向方法定义对象
                        _grid.on('afterRowDeleted', me.onGridEvent);
                        _grid.on('afterRowUpdated', me.onGridEvent);
                        _grid.on('afterRowUp', me.onGridEvent);
                        _grid.on('afterRowDown', me.onGridEvent);
                        break;
                    }
                    case 'list':
                        { 
                            //子元素结构不一致
                            var _list = {
                                xtype: 'list',
                                id: f.id || f.name ||p,
                                name: f.name || p,
                                itemKeyMember:f.itemKeyMember||'id',
                                dataIndex: _dataIndex,   
                                style:{
                                    overflow:'visible',
                                    borderRadius:'4px',
                                    backgroundColor:me.bgColors[_bgIndex],
                                },
                                label: {
                                    position:'top',
                                    xtype:'container', 
                                    align:'left',
                                    header:{
                                        content:'&nbsp;&nbsp;' + (f.title || f.$id),
                                        position:'left', 
                                        style:{backgroundColor:'transparent'}
                                    },
                                    space:0,
                                    style: {   
                                        fontSize:'100%', 
                                        lineHeight:40 
                                    },
                                    layout:{type:'hbox',align:'right'},
                                    items:me.getDefaultButtons(p,f) //列表头部按钮
                                },
                                margin:'0 0 0 2%',
                                width: '96%',
                                readonly: true,
                                border: true,
                                tabIndex: _index,  
                                layout: 'vbox',
                                wrap:false,//禁止换行
                                itemSchema:f.items,
                                itemXtype:'json-form',
                                itemStyle:{
                                    width:'90%',
                                    margin:'0 0 10px 5%',
                                    border:'1px grey soild',
                                    borderRadius:'5px',
                                    backgroundColor:'#78b6ed59'
                                },
                                buttons:f.buttons,//li node item 上的 buttons,
                                dataSource: f.examples || [],
                                forSchema:_schema//根schema
                            };
                             
                            //me.add({xtype:'component-x',height:10});
                            _list = me.add(_list);  
                            //string 方法名注册事件，方法体中，this指向方法定义对象
                            _list.on('afterItemDeleted',"onListEvents");//列表子项删除后
                            _list.on('itemUpdating','onListEvents');//列表子项修改
                            _list.on('afterItemUpdated', 'onListEvents');//列表子项修改后
                            _list.on('afterItemUp','onListEvents');//列表子项上移
                            _list.on('afterItemDown',"onListEvents");//列表子项下移
                            break;
                        }
                    case 'json-form':
                        {
                            //console.log('is object', f);
                            var _form = {
                                xtype: f.xtype||'json-form',
                                id: f.id || f.name ||p,
                                name: _dataIndex,
                                dataIndex: _dataIndex,
 
                                margin:'0 0 5px 2%',
                                height: "auto",//f.height || 60 + f.properties.length * 32,
                                width: '96%',
                                fieldWidth: me.fieldWidth||'45%',
                                style:{ 
                                    borderRadius:'4px',
                                    boxSizing:'border-box',
                                    border:'1px grey solid',
                                    backgroundColor:me.bgColors[_bgIndex],
                                },
                                readonly:me.readonly,
                                header: {
                                    xtype:'container',
                                    position:'top',
                                    space:0,
                                    height:40,
                                    align:'left',
                                    header: { 
                                        content:'&nbsp;&nbsp;' + (f.title || f.$id),  
                                        position:'left', 
                                        style:{backgroundColor:'transparent'}
                                    },
                                    style: {  
                                            fontSize:'100%', 
                                            lineHeight: f.height || 40, 
                                    },
                                    layout:{type:'hbox',align:'right'},
                                    items:f.buttons||me.getDefaultButtons(p,f) 
                                },
                                bodyStyle:{
                                    overflow:'visible',
                                    padding:'0px 0 10px 0'
                                },
                                layout:{
                                    type:'hbox',
                                    wrap:'wrap',
                                    content:'start start',
                                    align:'start'
                                },

                                parent:me, 
                                formSchema:f,
                                forSchema:_schema,//根schema
                                formEventHandler:me.formEventHandler//表单编辑时发生
                            }
                            //console.log('formEventHandler ,id is ' + me.id,me.formEventHandler);
                            _form = me.add(_form); 
                            //string 方法名注册事件，方法体中，this指向方法定义对象
                            _form.on('afterFormUpdated','onFormEvent');
                            break;
                        }
                    case 'checkbox': 
                    case 'text':
                    default: { 
                            //console.log(p,f.onblur,f.description,f);
                            var _value = (f.examples && f.examples.length > 0)?f.examples[0]:'';
                            //console.log(_xtype);
                            var _field = {
                                xtype:_xtype,
                                id: f.$id || f.name||p||'',
                                name: f.name || p,
                                dataIndex: _dataIndex,

                                tabIndex: _index,
                                placeholder:_value,
                                //margin: '4 0 4 0',
                                width: f.width || me.fieldWidth,
                                //height: f.height || 30,
                                
                                required: f.required===true, 
                                minLength: f.minLength||0,
                                maxLength: f.maxLength||99999,
                                pattern: f.pattern||'',
                                format: f.format||'', 
                                //value:_value,
                                "default": f.default||'',
                                label: {
                                    content: f.title || p || f.$id, 
                                    tip: f.description||'',
                                    style: {minWidth:60, lineHeight: f.height || 30,paddingLeft:'10px' }
                                }, 
                                onblur:f.onblur,
                                onchange:f.onchange

                            };
                            if(_xtype == 'checkbox')
                            {
                                 _field.mode ='check';
                            }
                            //console.log(f.title,_field);
                            if(Rsd.isArray(f.enum))
                            {
                                 _field["dataSource"] = f.enum;
                            }
                            if(Rsd.isString(f.enum))
                            {
                                _field["enum"] = f.enum;
                            }
                            if(f.height)
                            {
                                _field.height = f.height;
                            }
                            if(f.label)
                            {
                                _field.label = Rsd.apply(_field.label,f.label);
                            }
                            if(f.mulitiLine !== undefined)
                            {
                                _field.mulitiLine = f.mulitiLine; 
                            }
                            //console.log(_field);
                            if (f.labelStyle) {
                                _field.label.style = Rsd.apply(_field.label.style, f.labelStyle);
                                delete _field.label.text;
                            }
                            if (f.hasOwnProperty('readonly')) {
                                _field.readonly = (_readonly ? true : f.readonly);
                            }
                            else {
                                _field.readonly = _readonly;
                            }
                            var _h = 0;
                            if (_field.xtype != 'hidden') {
                                _h = _field.height || 40;
                            }
                            _w += _field.width || 0;
                            if (_field.width && _width && _w < _width) {
                            }
                            else {
                                _w = _field.width || 0;
                            }
                             //string 方法名注册事件，方法体中，this指向方法定义对象
                            _field.onchange = "onFieldValueChange";
                            //console.log('json form add field ===> ',_field.dataIndex,_field);
                            var _field = me.add(_field);
                           
                            break;
                    }
                }

            }
            catch (ex) {
                console.error('JsonFrom loadFields occured exception',ex);
            }

            _last_type = f.type;
        }
        // 
        me.doLayout();
        //
        if(callback)
        {  
            this.funApplyByIOC(callback,[schema]);
        }
    
        return this;
    }, 
   
     /**
     *@description 加载数据到field,file dataIndex属性 支持 . 多级分割
     * */
    loadData: function loadData(data) {

        var _data = data || this.data || {};
        if(Rsd.isEmpty(_data))
        {
            this.isLoaded = true;
            return;
        }
        this.data = _data;
        //console.log('json form load data,name or id: '+ (this.name || this.id),JSON.stringify(_data));

        var me = this;
       
        var id = setInterval (function(){

            if(!me.isLayout)
            {
                return;
            }
            clearInterval(id);
 
            var _item = null;
            var _dataIndex = null; 
            var _value = null;
            me.isLoaded = false;

            for (var i = 0; i < me.items.length; i++) {

                _item = me.items[i];
                _value = null;
                if(_item.$className === 'Rsd.common.ComponentX')
                {
                    continue;
                }
                _dataIndex = _item.dataIndex || _item.dataindex || '';
    
               if( !Rsd.isEmpty(_dataIndex))
               {
                    //获取值
                   try {

                       if (_data[_dataIndex] !== undefined) {
                           _value = _data[_dataIndex];
                       }
                       else {
                           var list = _dataIndex.split('.'); 
                           var j = 0;
                           var _p = _data;
                           while (list.length > 1 && j < list.length && Rsd.hasProperty(_p, list[j])) {
                               _p = _p[list[j]];
                               j++;
                           }
                           if (j == list.length) {
                               _value = _p;
                           }
                       }
                   }
                   catch (e) {
                       console.error('JsonForm LoadData Occured Exception', e);
                   }
               }
                //console.log('json form load [field] data ',_item.xtype,_dataIndex,JSON.stringify(_value));
                //设置值 优先 使用 setValue
                if(Rsd.isFunction(_item.setValue))
                {
                    _item.setValue(_value);
                    continue;
                }  
                //console.log(_item.xtype + '('+ (_item.name||'') +') ' + (_item.loadData ? 'has loadData function' : 'no loadData function'));
                //加载值
                if(_item instanceof Rsd.widget.JsonForm)
                {
                     var _d = {};
                     _d[_dataIndex] = _value;
                    _item.loadData(_data);
                     continue;
                }
                if(_item instanceof Rsd.control.List)
                { 
                    _item.loadData(_value);
                     continue;
                }
                if(_item instanceof Rsd.control.Grid)
                { 
                    _item.loadData(_value);
                     continue;
                }
                if(Rsd.isFunction(_item.loadData))
                {   
                    _item.loadData(_value);
                }
            }

            me.isLoaded = true;

            },100);

        return this;
    },
    /**
     * 
     * @param {*} schema 
     */
    getDefaultButtons:function getDefaultButtons(propertyName,schema)
    {
        if(this.getEditButtonsHandler)
        {
            return this.funApplyByIOC(this.getEditButtonsHandler,[propertyName,schema,this]);
        }
        return [];
    },

    /**
     * @description 验证控件输入值 是否有效
     *  */
    checkRecord: function checkRecord() {

        var _item = null;
        var _form = this;
        this.errorList = [];
        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i];

            if (!Rsd.isFunction(_item.checkValue)) {
                if(_item.xtype !=='component-x'  || _item.xtype !=='container' )
                {
                    continue;
                }
                console.warn();('Control [' + _item.$className + '('+_item.xtype+')] has no function \'checkValue\'.');
                continue;
            }

            try {
                if (!_item.checkValue()) {
                    this.errorList.push(_item.getError());
                }
            }
            catch (err) {
                console.error(err);
            }

        }

        return this.errorList.length == 0;
    },
    /**
    * @description 错误消息处理
    * @description handler:方法注入
    * */
    showError: function showError(handler) {

        if (this.errorList.length > 0) {
            if (handler) {
                handler.call(this, [this.errorList]);
            }
            else {
                Rsd.alert('错误提示', this.errorList);
            }
        }

    },
    /** 
    * @description 将控件获取到到数据合并到 参数obj 或data 中返回；
    * @description 在获取前，应先验证form的数据是否全部有效，
    *
    * */
    getRecord: function getRecord(obj) {

        var _obj = obj || this.data || {};
        //console.log('json form getRecord {dataIndex,data }',this.dataIndex,JSON.stringify(_obj));
        
        var me = this;
        var _item = null;
        var _form = me;
         
         if(_form.dataIndex)
         {
            if(!_obj[_form.dataIndex])
            {
                _obj[_form.dataIndex] = {};
            }
            _obj = _obj[_form.dataIndex];
         }
         
        //console.log('json form data',_form.dataIndex||'-root-',JSON.stringify(_obj));

        for (var i = 0; i < _form.items.length; i++) {

            _item = _form.items[i]; 
            if (_item.readonly) {
                //continue;
            }
            var _dataIndex = _item.dataIndex || _item.dataindex || _item.name;
            
            if (Rsd.isEmpty(_dataIndex)) {
                continue;
            }
            if(_dataIndex.startWith((_form.dataIndex+'.')))
            {
                _dataIndex = _dataIndex.substring(_form.dataIndex.length +1);
            }
          
            //continue;

            var _data = _obj;
            var _value = _obj[_dataIndex];
            var _no_value = true;
            //需要区别出 数据已加载 和 数据加载中 两种状态，而从决定 是否出发formfieldchange 事件
            //form control
            if(_no_value && Rsd.isFunction(_item.getValue))
            {
                _value = _item.getValue(); 
                _no_value = false;
            }
            //json form
            if(_no_value && Rsd.isFunction(_item.getRecord))
            {
                _value = _item.getRecord(); 
                _no_value = false;
            }
            //list ,grid 
            if(_no_value && Rsd.isFunction(_item.getData))
            {
                _value = _item.getData(); 
                _no_value = false;
            }
            if(_no_value)
            { 
                console.error('JsonForm未识别的控件',_item);
                continue;
            }
            //console.log("json form get field ["+_dataIndex+"] value :",_value,JSON.stringify(_obj)); 
            arr =  _dataIndex.split('.');
            if(arr.length == 1 )
            {
                _data[_dataIndex] = _value; 
                continue;
            }

            //整理数据
            for(var j in arr)
            {
                
                if(j == arr.length -1)
                {
                     _data[arr[j]] = _value; 
                }
                else
                {
                    if(!_data[arr[j]])
                    {
                        _data[arr[j]] = {};
                    }
                    _data = _data[arr[j]];
                } 
            }
          
        } 
        //console.log('json form getRecord',_form.dataIndex||'',_obj);
        return _obj;

    },
    /**
    *
    * @description 获取字段值
    * */
    getFieldValue: function getFieldValue(name) {
        var _obj = this.data || {};
        var me = this;
        var _item = null;
        var _form = me;

        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i];
            if (_item.readonly) {
                continue;
            }
            if(Rsd.isFunction(_item.getValue))
            {
                _obj[_item.dataIndex || _item.dataindex] = _item.getValue();
            }
            
        }

        return _obj[name];
    }, 
    /*
    *@param key:index or name or id  or xtype
    * */
    getFieldControl: function getFieldControl(key) {
        if (Rsd.isNumber(key)) {
            return this.items[key];
        }
        return this.getItemByName(key) || this.getItemById(key) || this.getItemByXtype(key);
    },
    /**
     * 
     */
    getScrollHeight: function getScrollHeight() {
        return this.body.scrollHeight;
    },
    /**
     * 子控件 grid 表格, 发生的事件
     * @param {*} name 
     * @param {*} grid 
     * @param {*} s 
     * @param {*} e 
     */
    onGridEvent:function onGridEvent(name,grid,s,e)
    { 
        //console.log('onGridEvent',name,grid,s,e);
        var _data = this.getRecord();
        this.eventHandler(name,_data,grid.dataIndex,s,e); 
    },
    /**
     *  子控件 list 列表, 发生的事件
     * @param {*} s 
     * @param {*} e 
     */
    onListEvents:function onListEvents(name,list,s,e,c)
    {  
        //console.log("onListEvents(name,list,s,e)",arguments);
        var _data = this.getRecord();
        this.eventHandler(name,_data,list.dataIndex,s,e,c); 
    },
    /**
     * 子控件 form表单, 发生的事件
     */
    onFormEvent:function onFormEvent(s,e)
    {
        console.log('onFormEvent',arguments)
        var _data = this.getRecord();
        this.eventHandler('formEvent',_data,s.dataIndex,s,e);
    },
    /**
     * 录入控件 发生事件
     * @param {*} s 
     * @param {*} e 
     */
    onFieldValueChange:function onFieldValueChange(s,e)
    {  
         //需要区别出 数据已加载 和 数据加载中 两种状态，而从决定 是否出发formfieldchange 事件
        if(this.isLoaded === false)
        {
            return;
        }
        var _data = this.getRecord(); 
        //console.log('json form onFieldValueChange',s,_data,s.dataIndex,s.getValue());
        this.eventHandler('fieldValueChange',_data,s.dataIndex,s,e);
    },
    /**
     * 以上 子控件事件 最终汇聚
     * @param {*} name 
     * @param {*} data 
     * @param {*} dataIndex 
     * @param {*} sender 
     * @param {*} evt 
     * @param {*} config ,sender 对象配置信息 
     */
    eventHandler:function eventHandler(name,data,dataIndex,sender,evt,config)
    { 
        if(this.formEventHandler)
        {
             //console.log('json form eventHandler',this,arguments);
            this.funApplyByIOC(this.formEventHandler,[name,data,dataIndex,sender,evt,config]); 
        }
        else
        {
            console.error('JsonForm未设置formEventHandler属性'); 
        }
    }


}, function (type) {

    var _dataGetter = function () {

        if (!this.hasOwnProperty('__data')) {
            this.__data = {};
        }
        return this.__data;
    };
    var _dataSetter = function (value) {

        this.__data = value;
        return;

    };
    this.defineProperty(type, "data", _dataGetter, _dataSetter, true);

    //
    this.defineProperty(type, "isLoaded", function () {

        if (!this.hasOwnProperty('__isLoaded')) {
            this.__isLoaded = null;//null ，未触发加载，false 加载中，true 已加载完毕
        }
        return this.__isLoaded;

    }, function (value) {
        this.__isLoaded = value;
    } , false);

});
